package Base;

import java.util.LinkedList;

class BaseCycle {

	protected LinkedList<Cycle> cycles;
	protected final int DIMENSION;
	protected Graphe g;
	protected LinkedList<Temoin> temoins;

	public BaseCycle(Graphe g){
		DIMENSION=Graphe.NOMBREARRETES-Graphe.NOMBRESOMMETS+g.composantesConnexe.size();
		cycles=new LinkedList<Cycle>();
		this.g=g;
	}

	/**
	 * Calcule la base de cycles élémentaires d'un graphe
	 * @param g Graphe dont on veut calculer la base de cycles élémentaires
	 */
	public void calculerBaseCycle(){

		System.out.println("\tCalcul de la base de cycle...");

		Arbre arbre=new Arbre(g);
		LinkedList<Arete> aretesGraphe=g.getAretes();
		LinkedList<Arete> aretesArbre=arbre.getAretes();
		LinkedList<Arete> aretesTemoin=arbre.calculTemoin(aretesGraphe, aretesArbre);

		System.out.println("\t\tCalcul des vecteurs témoins...");
		temoins=new LinkedList<Temoin>();
		for(Arete a:aretesTemoin){
			temoins.add(new Temoin(a));
		}

		System.out.println("\t\tCalcul récursif des cylces...");
		calculRecursif(cycles,temoins,DIMENSION);
	}

	/**
	 * Calcul récursivement les cycles
	 * @param cycles Liste de cycles
	 * @param temoins Liste des vecteurs témoins
	 * @param k
	 */
	public void calculRecursif(LinkedList<Cycle> cycles,LinkedList<Temoin> temoins,final int k){

		if(k==1){
			System.out.println("--------- Vérifier l'ajout de chaque cycle calculé -------------");
			cycles.add(g.calculerCycle(temoins));
		}
		else{
			calculRecursif(cycles, moitie1(temoins), k/2);

			System.out.println("----------- arguments de update à mettre au point ------------");
			// supposition
			// Temoin.update(le premier de la 2ème moitié mis à jour,le reste de la 2ème moitié);
			Temoin.update(new LinkedList<Temoin>(), new LinkedList<Temoin>());

			calculRecursif(cycles, moitie2(temoins), k/2);
		}

	}

	/**
	 * Retourne la 1ère moitié d'une liste 
	 * @param liste
	 * @return 1ère moité de la liste
	 */
	public static LinkedList<Temoin> moitie1(LinkedList<Temoin> liste){
		LinkedList<Temoin> l=new LinkedList<Temoin>();
		for(int i=0;i<liste.size()/2;i++){
			l.add(liste.get(i));
		}
		return l;
	}
	
	/**
	 * Retourne la 2ème moitié d'une liste 
	 * @param liste
	 * @return 2ème moitié de la liste
	 */
	public static LinkedList<Temoin> moitie2(LinkedList<Temoin> liste){
		LinkedList<Temoin> l=new LinkedList<Temoin>();
		for(int i=liste.size()/2;i<liste.size();i++){
			l.add(liste.get(i));
		}
		return l;
	}

}